package com.benio.ycfdisplayer;

import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import com.benio.ycfdisplayer.displayer.DisplayListener;
import com.benio.ycfdisplayer.displayer.Options;
import com.benio.ycfdisplayer.displayer.SimpleDisplayListener;
import com.benio.ycfdisplayer.displayer.YcfDisplayer;
import com.benio.ycfdisplayer.fresco.BitmapDisplayListener;
import com.benio.ycfdisplayer.fresco.CloseableBitmapTarget;
import com.benio.ycfdisplayer.fresco.CloseableViewTarget;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;

public class BitmapExecutorActivity extends AppCompatActivity {
    private static final String TAG = "Fresco";
    private CloseableBitmapTarget mCloseableBitmapTarget;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bitmap_executor);
        YcfDisplayer.initialize(this);

        /**
         * 注意，这里有一些要求！
         * 1.这些方式无法用来获取动图。
         * 2.你无法在onSuccess或者setBitmapInto之外的地方使用这个Bitmap。原因是BaseBitmapDataSubscriber数据源的获取结束之后，image pipeline就会回收这个Bitmap。
         * 如果你此时再用它来显示，会报IllegalStateException！
         * 3.当然你可以将它传给Android的通知栏或者[RemoveView]remote view。Android系统会在共享内存区域保存一份Bitmap的拷贝，Fresco的回收不会影响它。
         */
        /**
         * 模拟器上加载多张大图，反复销毁创建该Activity的话，会出现
         * java.lang.RuntimeException: Canvas: trying to use a recycled bitmap
         * 猜测可能是因为android 5.0以下，Bitmap是缓存在ashmem区域。模拟器ashmem区域比较小
         * 当系统内存不够的时候会强制释放ashmem, 导致维护的Bitmap被recycled？
         * 解决：调整模拟器的VM heap大小，默认64mb -> 512 mb
         */
        String uri1 = "http://img.tuwan.com/v2/thumb/all/Yjk1MiwwLDAsNCwzLDEsLTEsMSw=/u/img.tuwan.com/static/default/201408/1-14081302390220.jpg";
        String uri2 = "http://img.tuwan.com/v2/thumb/all/NDZlNiwwLDAsNCwzLDEsLTEsMSw=/u/img.tuwan.com/static/default/201408/1-1408130238538.jpg";
        String uri3 = "http://img2.imgtn.bdimg.com/it/u=2235927903,1693536379&fm=214&gp=0.jpg";
        String uri4 = "http://img15.3lian.com/2015/c1/83/d/33.jpg";
        final ImageView view1 = (ImageView) findViewById(R.id.image1);
        final ImageView view2 = (ImageView) findViewById(R.id.image2);

        /**
         * 因为这里是加载Bitmap，会使用{@link com.benio.ycfdisplayer.fresco.BitmapExecutor}
         * 此处Options如果使用{@link com.benio.ycfdisplayer.fresco.FrescoDisplayOptions}的话，
         * 只能使用ImageRequest的设置属性，设置其他属性无效
         */
        Options options = new Options.Builder()
                .setPlaceHolderImage(new ColorDrawable(Color.BLUE))
                .setFailureImage(new ColorDrawable(Color.RED))
                .build();

        DisplayListener listener = new MyDisplayListener();
        // 加载到ImageView
        YcfDisplayer.get().display(uri1).options(options).listener(listener).into(view1);

        // 加载到Target
        mCloseableBitmapTarget = (CloseableViewTarget) YcfDisplayer.get().display(uri2).into(new MyBitmapTarget(view2));
    }

    private static class MyListener extends BitmapDisplayListener {
        private Reference<ImageView> mImageViewReference;

        // 使用静态类+WeakReference，防止内存泄露
        public MyListener(ImageView imageView) {
            mImageViewReference = new WeakReference<ImageView>(imageView);
        }

        @Override
        public void onSuccess(String imageUri, View view, Bitmap bitmap) {
            Log.d(TAG, "onSuccess() called with: imageUri = [" + imageUri + "], view = [" + view + "], loadedData = [" + bitmap + "]");
            ImageView imageView = mImageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }

        @Override
        public void onStart(String imageUri, View view) {
            Log.d(TAG, "onStart() called with: imageUri = [" + imageUri + "], view = [" + view + "]");
        }

        @Override
        public void onFailure(String imageUri, View view, Throwable throwable) {
            Log.d(TAG, "onFailure() called with: imageUri = [" + imageUri + "], view = [" + view + "], throwable = [" + throwable + "]");
        }
    }

    private static class MyDisplayListener extends SimpleDisplayListener {
        @Override
        public void onStart(String imageUri, View view) {
            Log.d(TAG, "onStart() called with: imageUri = [" + imageUri + "], view = [" + view + "]");
        }

        @Override
        public void onSuccess(String imageUri, View view, Object loadedData) {
            Log.d(TAG, "onSuccess() called with: imageUri = [" + imageUri + "], view = [" + view + "], loadedData = [" + loadedData + "]");
        }

        @Override
        public void onFailure(String imageUri, View view, Throwable throwable) {
            Log.d(TAG, "onFailure() called with: imageUri = [" + imageUri + "], view = [" + view + "], throwable = [" + throwable + "]");
        }
    }

    private static class MyBitmapTarget extends CloseableViewTarget<ImageView> {

        public MyBitmapTarget(ImageView view) {
            super(view);
        }

        @Override
        protected void setDrawableInto(Drawable drawable, ImageView view) {
            view.setImageDrawable(drawable);
        }

        @Override
        protected void setBitmapInto(Bitmap bitmap, ImageView view) {
            view.setImageBitmap(bitmap);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mCloseableBitmapTarget.close();
    }
}
